Alumna: Nicole Muñoz
Profesor: Víctor Macías
Ayudante: Gabriel Cabrera

Pregunta 2

Librarías

library(quantmod)
library(dplyr)
library(plotly)
library(gridExtra)
library(tidyverse)
library(tidyquant)
library(forcats)
library(devtools)

Función

acciones <- c("AAPL","MSFT")
data <- tq_get(acciones,
               get = "stock.prices",
               from = "2000-01-01",
               to  = "2018-08-30",
               periodicity = "monthly")
data <- data.frame(data$symbol, data$date, data$close)
data <- data%>%rename(accion=data.symbol,
                      fecha=data.date,
                      precio=data.close)
finance = function(x,return=c('yes','no'),plot=c('type 1','type 2'),normal=c('yes','no')){
  
  #retornos log
  if (return=='yes'){
    retornoslog <- x %>%
      group_by(accion) %>%
      tq_transmute(select = precio,
                   mutate_fun = periodReturn,
                   period = "monthly",
                   type = "log",
                   col_rename = "retornos")
    dataA <- subset(retornoslog, accion=="AAPL")
    dataM <- subset(retornoslog, accion=="MSFT")
    dataA <- dataA %>% mutate(retcumA = cumsum(retornos))
    dataM <- dataM %>% mutate(retcumM = cumsum(retornos)) 
    
    #grafico 11:retornos log
    ifelse(plot=='type 1',
           g11 <- plot_ly(dataA, x = ~fecha) %>%
             add_lines(y = ~dataA$retornos, name = "APPLE", line = list(color = 'rgb(19,135,171)', width = 2)) %>% 
             add_lines(y = ~dataM$retornos, name = "MICROSOFT", line = list(color = 'rgb(153,171,254)', width = 2)) %>%
             layout(
               title = "RETORNOS (logarítmicos) APPLE & MICROSOFT",
               xaxis = list(
                 rangeselector = list(
                   buttons = list(
                     list(
                       count = 3,
                       label = "3 mo",
                       step = "month",
                       stepmode = "backward"),
                     list(
                       count = 6,
                       label = "6 mo",
                       step = "month",
                       stepmode = "backward"),
                     list(
                       count = 1,
                       label = "1 yr",
                       step = "year",
                       stepmode = "backward"),
                     list(
                       count = 1,
                       label = "YTD",
                       step = "year",
                       stepmode = "todate"),
                     list(step = "all"))),
                 
                 rangeslider = list(type = "Fecha")),
               yaxis = list(title = "Retornos")),
           
           ifelse(
             plot=='type 2',
                  g12 <- plot_ly(dataA, x = ~fecha) %>%
                    add_lines(y = ~dataA$retcumA, name = "APPLE", line = list(color = 'rgb(19,135,171)', width = 2)) %>% 
                    add_lines(y = ~dataM$retcumM, name = "MICROSOFT", line = list(color = 'rgb(153,171,254)', width = 2)) %>%
                    layout(
                      title = "RETORNOS ACUMULADOS (logarítmicos) APPLE & MICROSOFT",
                      xaxis = list(
                        rangeselector = list(
                          buttons = list(
                            list(
                              count = 3,
                              label = "3 mo",
                              step = "month",
                              stepmode = "backward"),
                            list(
                              count = 6,
                              label = "6 mo",
                              step = "month",
                              stepmode = "backward"),
                            list(
                              count = 1,
                              label = "1 yr",
                              step = "year",
                              stepmode = "backward"),
                            list(
                              count = 1,
                              label = "YTD",
                              step = "year",
                              stepmode = "todate"),
                            list(step = "all"))),
                        
                        rangeslider = list(type = "Fecha")),
                      
                      yaxis = list(title = "Retornos"))
           )#ifelse dentro de los graficos
    )#fin ifelse graficos 
  
    jlog = by(retornoslog,retornoslog$accion,
              function(x){
                n=length(x$retornos)
                mean = sum(x$retornos)/n
                skewness = ((sum(x$retornos-mean)^3)/n)/((sum(x$retornos-mean)^2)/n)^(3/2)
                kurtosis = ((sum(x$retornos-mean)^4)/n)/((sum(x$retornos-mean)^2)/n)^2
                JB = n*(((skewness^2)/6)+(((kurtosis-3)^2)/24))
                j = paste('p-value =',1 - pchisq(JB,df = 2),ifelse(1 - pchisq(JB,df = 2)<0.05,
                                                                   ', se rechaza la hipotesis nula de normalidad para los retornos de Apple',
                                                                   ', no se rechaza la hipotesis nula de normalidad para los retornos de Microsoft'))})
    }#fin primer if si return=yes
  #retornos aritmeticos
  else if (return=='no'){
    retornosimple <- x %>% 
      group_by(accion) %>%
      tq_transmute(select = precio,
                 mutate_fun = periodReturn,
                 period = "monthly",
                 type = "arithmetic",
                 col_rename = "retornos")
    dataA1 <- subset(retornosimple, accion=="AAPL")
    dataM1 <- subset(retornosimple, accion=="MSFT")
    dataA1 <- dataA1 %>% mutate(retcumA = cumsum(retornos))
    dataM1 <- dataM1 %>% mutate(retcumM = cumsum(retornos))
    
    
    ifelse(plot=='type 1',
           g21 <- plot_ly(dataA1, x = ~fecha) %>%
             add_lines(y = ~dataA1$retornos, name = "APPLE", line = list(color = 'rgb(19,135,171)', width = 2)) %>% 
             add_lines(y = ~dataM1$retornos, name = "MICROSOFT", line = list(color = 'rgb(153,171,254)', width = 2)) %>%
             layout(
               title = "RETORNOS (aritméticos) APPLE & MICROSOFT",
               xaxis = list(
                 rangeselector = list(
                   buttons = list(
                     list(
                       count = 3,
                       label = "3 mo",
                       step = "month",
                       stepmode = "backward"),
                     list(
                       count = 6,
                       label = "6 mo",
                       step = "month",
                       stepmode = "backward"),
                     list(
                       count = 1,
                       label = "1 yr",
                       step = "year",
                       stepmode = "backward"),
                     list(
                       count = 1,
                       label = "YTD",
                       step = "year",
                       stepmode = "todate"),
                     list(step = "all"))),
                 
                 rangeslider = list(type = "Fecha")),
               
               yaxis = list(title = "Retornos")),
           ifelse(plot=='type 2',
                  g22 <- plot_ly(dataA1, x = ~fecha) %>%
                    add_lines(y = ~dataA1$retcumA, name = "APPLE", line = list(color = 'rgb(19,135,171)', width = 2)) %>% 
                    add_lines(y = ~dataM1$retcumM, name = "MICROSOFT", line = list(color = 'rgb(153,171,254)', width = 2)) %>%
                    layout(
                      title = "RETORNOS ACUMULADOS (aritméticos) APPLE & MICROSOFT",
                      xaxis = list(
                        rangeselector = list(
                          buttons = list(
                            list(
                              count = 3,
                              label = "3 mo",
                              step = "month",
                              stepmode = "backward"),
                            list(
                              count = 6,
                              label = "6 mo",
                              step = "month",
                              stepmode = "backward"),
                            list(
                              count = 1,
                              label = "1 yr",
                              step = "year",
                              stepmode = "backward"),
                            list(
                              count = 1,
                              label = "YTD",
                              step = "year",
                              stepmode = "todate"),
                            list(step = "all"))),
                        
                        rangeslider = list(type = "Fecha")),
                      
                      yaxis = list(title = "Retornos"))
                  )#fin ifelse grafico tipo 2
           ) #fin primer ifelse grafico tipo 1
    
    j_arit= by(retornosimple,retornosimple$accion,
               function(x){
                 n=length(x$retornos)
                 mean = sum(x$retornos)/n
                 skewness = ((sum(x$retornos-mean)^3)/n)/((sum(x$retornos-mean)^2)/n)^(3/2)
                 kurtosis = ((sum(x$retornos-mean)^4)/n)/((sum(x$retornos-mean)^2)/n)^2
                 JB = n*(((skewness^2)/6)+(((kurtosis-3)^2)/24))
                 j = paste('p-value =',1 - pchisq(JB,df = 2),
                           ifelse(1 - pchisq(JB,df = 2)<0.05,
                                  ', se rechaza la hipotesis nula de normalidad para los retornos de Apple',
                                  ', no se rechaza la hipotesis nula de normalidad para los retornos de Microsoft'))})
    }#fin else if retornos=no
  
  #debemos general el resultado normal==no y dado que en ambos casos se realiza el test, programamos la salida:
  no="Se realizó test de Normalidad, ocultando su resultado"
  
  #debemos generar todas las posibles salidas
  ifelse(return=="yes"& plot=='type 1' & normal=="yes",return(list(g11,jlog)),
         ifelse(return=='yes' & plot=='type 2' & normal=="yes",return(list(g12,jlog)),
                ifelse(return=='yes' & plot=='type 1' & normal=="no",return(list(g11,no)),
                       ifelse(return=='yes' & plot=='type 2' & normal=="no",return(list(g12,no)),
                              ifelse(return=='no' & plot=='type 1' & normal=="yes",return(list(g21,j_arit)),
                                     ifelse(return=='no' & plot=='type 2' & normal=="yes",return(list(g22,j_arit)),
                                            ifelse(return=='no' & plot=='type 1' & normal=="no",return(list(g21,no)),
                                                   ifelse(return=='no' & plot=='type 2' & normal=="no",return(list(g22,no))))))))
                
         ))
  
  
  }#fin funcion

Resultados

finance(data,"yes","type 1","yes")
[[1]]


[[2]]
retornoslog$accion: AAPL
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
--------------------------------------------------------- 
retornoslog$accion: MSFT
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
finance(data,"no","type 1","yes")
[[1]]


[[2]]
retornosimple$accion: AAPL
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
--------------------------------------------------------- 
retornosimple$accion: MSFT
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
finance(data, "yes", "type 2", "yes")
[[1]]


[[2]]
retornoslog$accion: AAPL
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
--------------------------------------------------------- 
retornoslog$accion: MSFT
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
finance(data, "no", "type 2", "yes")
[[1]]


[[2]]
retornosimple$accion: AAPL
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"
--------------------------------------------------------- 
retornosimple$accion: MSFT
[1] "p-value = 0 , se rechaza la hipotesis nula de normalidad para los retornos de Apple"

Pregunta 3


LS0tCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiB5ZXRpCi0tLQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KaHRtbHRvb2xzOjp0YWdMaXN0KHJtYXJrZG93bjo6aHRtbF9kZXBlbmRlbmN5X2ZvbnRfYXdlc29tZSgpKQpgYGAKCgoKCjxoZWFkPgo8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImJ0biBidG4tcHJpbWFyeSBidG4tbGcgYnRuLWJsb2NrIj48aDE+PGI+PGkgY2xhc3M9ImZhYiBmYS1naXRodWIiPjwvaT4gVEFSRUEgNTwvYj48L2gxPjwvYnV0dG9uPgo8YnI+CjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWRpc21pc3NpYmxlIGFsZXJ0LWluZm8iPgogIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iY2xvc2UiIGRhdGEtZGlzbWlzcz0iYWxlcnQiPiZ0aW1lczs8L2J1dHRvbj4KICA8c3Ryb25nPkFsdW1uYTo8L3N0cm9uZz4gTmljb2xlIE11w7FveiA8YnI+CiAgPHN0cm9uZz5Qcm9mZXNvcjo8L3N0cm9uZz4gVsOtY3RvciBNYWPDrWFzIDxicj4KICA8c3Ryb25nPkF5dWRhbnRlOjwvc3Ryb25nPiBHYWJyaWVsIENhYnJlcmEgPGJyPgogIAo8L2Rpdj4KPC9oZWFkPgoKCiMgPGEgaHJlZj0iIyI+PGkgY2xhc3M9ImZhcyBmYS1xdWVzdGlvbi1jaXJjbGUiPjwvaT48Yj4gUHJlZ3VudGEgMjwvYj48L2E+ey50YWJzZXR9CgoKPGkgY2xhc3M9ImZhcyBmYS1ib29rIj48L2k+IExpYnJhcsOtYXMKLS0tLS0tLS0tLS0tLQpgYGB7cn0KbGlicmFyeShxdWFudG1vZCkKbGlicmFyeShkcGx5cikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWR5cXVhbnQpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShkZXZ0b29scykKYGBgCgoKCjxpIGNsYXNzPSJmYXMgZmEtY29kZSI+PC9pPiBGdW5jacOzbgotLS0tLS0tLS0tLS0tCgpgYGB7cn0KYWNjaW9uZXMgPC0gYygiQUFQTCIsIk1TRlQiKQpkYXRhIDwtIHRxX2dldChhY2Npb25lcywKICAgICAgICAgICAgICAgZ2V0ID0gInN0b2NrLnByaWNlcyIsCiAgICAgICAgICAgICAgIGZyb20gPSAiMjAwMC0wMS0wMSIsCiAgICAgICAgICAgICAgIHRvICA9ICIyMDE4LTA4LTMwIiwKICAgICAgICAgICAgICAgcGVyaW9kaWNpdHkgPSAibW9udGhseSIpCmRhdGEgPC0gZGF0YS5mcmFtZShkYXRhJHN5bWJvbCwgZGF0YSRkYXRlLCBkYXRhJGNsb3NlKQpkYXRhIDwtIGRhdGElPiVyZW5hbWUoYWNjaW9uPWRhdGEuc3ltYm9sLAogICAgICAgICAgICAgICAgICAgICAgZmVjaGE9ZGF0YS5kYXRlLAogICAgICAgICAgICAgICAgICAgICAgcHJlY2lvPWRhdGEuY2xvc2UpCmZpbmFuY2UgPSBmdW5jdGlvbih4LHJldHVybj1jKCd5ZXMnLCdubycpLHBsb3Q9YygndHlwZSAxJywndHlwZSAyJyksbm9ybWFsPWMoJ3llcycsJ25vJykpewogIAogICNyZXRvcm5vcyBsb2cKICBpZiAocmV0dXJuPT0neWVzJyl7CiAgICByZXRvcm5vc2xvZyA8LSB4ICU+JQogICAgICBncm91cF9ieShhY2Npb24pICU+JQogICAgICB0cV90cmFuc211dGUoc2VsZWN0ID0gcHJlY2lvLAogICAgICAgICAgICAgICAgICAgbXV0YXRlX2Z1biA9IHBlcmlvZFJldHVybiwKICAgICAgICAgICAgICAgICAgIHBlcmlvZCA9ICJtb250aGx5IiwKICAgICAgICAgICAgICAgICAgIHR5cGUgPSAibG9nIiwKICAgICAgICAgICAgICAgICAgIGNvbF9yZW5hbWUgPSAicmV0b3Jub3MiKQogICAgZGF0YUEgPC0gc3Vic2V0KHJldG9ybm9zbG9nLCBhY2Npb249PSJBQVBMIikKICAgIGRhdGFNIDwtIHN1YnNldChyZXRvcm5vc2xvZywgYWNjaW9uPT0iTVNGVCIpCiAgICBkYXRhQSA8LSBkYXRhQSAlPiUgbXV0YXRlKHJldGN1bUEgPSBjdW1zdW0ocmV0b3Jub3MpKQogICAgZGF0YU0gPC0gZGF0YU0gJT4lIG11dGF0ZShyZXRjdW1NID0gY3Vtc3VtKHJldG9ybm9zKSkgCiAgICAKICAgICNncmFmaWNvIDExOnJldG9ybm9zIGxvZwogICAgaWZlbHNlKHBsb3Q9PSd0eXBlIDEnLAogICAgICAgICAgIGcxMSA8LSBwbG90X2x5KGRhdGFBLCB4ID0gfmZlY2hhKSAlPiUKICAgICAgICAgICAgIGFkZF9saW5lcyh5ID0gfmRhdGFBJHJldG9ybm9zLCBuYW1lID0gIkFQUExFIiwgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDE5LDEzNSwxNzEpJywgd2lkdGggPSAyKSkgJT4lIAogICAgICAgICAgICAgYWRkX2xpbmVzKHkgPSB+ZGF0YU0kcmV0b3Jub3MsIG5hbWUgPSAiTUlDUk9TT0ZUIiwgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDE1MywxNzEsMjU0KScsIHdpZHRoID0gMikpICU+JQogICAgICAgICAgICAgbGF5b3V0KAogICAgICAgICAgICAgICB0aXRsZSA9ICJSRVRPUk5PUyAobG9nYXLDrXRtaWNvcykgQVBQTEUgJiBNSUNST1NPRlQiLAogICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QoCiAgICAgICAgICAgICAgICAgcmFuZ2VzZWxlY3RvciA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICBidXR0b25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiMyBtbyIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiNiBtbyIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiMSB5ciIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICBzdGVwbW9kZSA9ICJiYWNrd2FyZCIpLAogICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJZVEQiLAogICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAieWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAidG9kYXRlIiksCiAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3RlcCA9ICJhbGwiKSkpLAogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHJhbmdlc2xpZGVyID0gbGlzdCh0eXBlID0gIkZlY2hhIikpLAogICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiUmV0b3Jub3MiKSksCiAgICAgICAgICAgCiAgICAgICAgICAgaWZlbHNlKAogICAgICAgICAgICAgcGxvdD09J3R5cGUgMicsCiAgICAgICAgICAgICAgICAgIGcxMiA8LSBwbG90X2x5KGRhdGFBLCB4ID0gfmZlY2hhKSAlPiUKICAgICAgICAgICAgICAgICAgICBhZGRfbGluZXMoeSA9IH5kYXRhQSRyZXRjdW1BLCBuYW1lID0gIkFQUExFIiwgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDE5LDEzNSwxNzEpJywgd2lkdGggPSAyKSkgJT4lIAogICAgICAgICAgICAgICAgICAgIGFkZF9saW5lcyh5ID0gfmRhdGFNJHJldGN1bU0sIG5hbWUgPSAiTUlDUk9TT0ZUIiwgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDE1MywxNzEsMjU0KScsIHdpZHRoID0gMikpICU+JQogICAgICAgICAgICAgICAgICAgIGxheW91dCgKICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlJFVE9STk9TIEFDVU1VTEFET1MgKGxvZ2Fyw610bWljb3MpIEFQUExFICYgTUlDUk9TT0ZUIiwKICAgICAgICAgICAgICAgICAgICAgIHhheGlzID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VzZWxlY3RvciA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIjMgbW8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwID0gIm1vbnRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiNiBtbyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAibW9udGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwbW9kZSA9ICJiYWNrd2FyZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICIxIHlyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiWVREIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAidG9kYXRlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN0ZXAgPSAiYWxsIikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlc2xpZGVyID0gbGlzdCh0eXBlID0gIkZlY2hhIikpLAogICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiUmV0b3Jub3MiKSkKICAgICAgICAgICApI2lmZWxzZSBkZW50cm8gZGUgbG9zIGdyYWZpY29zCiAgICApI2ZpbiBpZmVsc2UgZ3JhZmljb3MgCiAgCiAgICBqbG9nID0gYnkocmV0b3Jub3Nsb2cscmV0b3Jub3Nsb2ckYWNjaW9uLAogICAgICAgICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgICAgICAgbj1sZW5ndGgoeCRyZXRvcm5vcykKICAgICAgICAgICAgICAgIG1lYW4gPSBzdW0oeCRyZXRvcm5vcykvbgogICAgICAgICAgICAgICAgc2tld25lc3MgPSAoKHN1bSh4JHJldG9ybm9zLW1lYW4pXjMpL24pLygoc3VtKHgkcmV0b3Jub3MtbWVhbileMikvbileKDMvMikKICAgICAgICAgICAgICAgIGt1cnRvc2lzID0gKChzdW0oeCRyZXRvcm5vcy1tZWFuKV40KS9uKS8oKHN1bSh4JHJldG9ybm9zLW1lYW4pXjIpL24pXjIKICAgICAgICAgICAgICAgIEpCID0gbiooKChza2V3bmVzc14yKS82KSsoKChrdXJ0b3Npcy0zKV4yKS8yNCkpCiAgICAgICAgICAgICAgICBqID0gcGFzdGUoJ3AtdmFsdWUgPScsMSAtIHBjaGlzcShKQixkZiA9IDIpLGlmZWxzZSgxIC0gcGNoaXNxKEpCLGRmID0gMik8MC4wNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcsIHNlIHJlY2hhemEgbGEgaGlwb3Rlc2lzIG51bGEgZGUgbm9ybWFsaWRhZCBwYXJhIGxvcyByZXRvcm5vcyBkZSBBcHBsZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLCBubyBzZSByZWNoYXphIGxhIGhpcG90ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgcGFyYSBsb3MgcmV0b3Jub3MgZGUgTWljcm9zb2Z0JykpfSkKICAgIH0jZmluIHByaW1lciBpZiBzaSByZXR1cm49eWVzCiAgI3JldG9ybm9zIGFyaXRtZXRpY29zCiAgZWxzZSBpZiAocmV0dXJuPT0nbm8nKXsKICAgIHJldG9ybm9zaW1wbGUgPC0geCAlPiUgCiAgICAgIGdyb3VwX2J5KGFjY2lvbikgJT4lCiAgICAgIHRxX3RyYW5zbXV0ZShzZWxlY3QgPSBwcmVjaW8sCiAgICAgICAgICAgICAgICAgbXV0YXRlX2Z1biA9IHBlcmlvZFJldHVybiwKICAgICAgICAgICAgICAgICBwZXJpb2QgPSAibW9udGhseSIsCiAgICAgICAgICAgICAgICAgdHlwZSA9ICJhcml0aG1ldGljIiwKICAgICAgICAgICAgICAgICBjb2xfcmVuYW1lID0gInJldG9ybm9zIikKICAgIGRhdGFBMSA8LSBzdWJzZXQocmV0b3Jub3NpbXBsZSwgYWNjaW9uPT0iQUFQTCIpCiAgICBkYXRhTTEgPC0gc3Vic2V0KHJldG9ybm9zaW1wbGUsIGFjY2lvbj09Ik1TRlQiKQogICAgZGF0YUExIDwtIGRhdGFBMSAlPiUgbXV0YXRlKHJldGN1bUEgPSBjdW1zdW0ocmV0b3Jub3MpKQogICAgZGF0YU0xIDwtIGRhdGFNMSAlPiUgbXV0YXRlKHJldGN1bU0gPSBjdW1zdW0ocmV0b3Jub3MpKQogICAgCiAgICAKICAgIGlmZWxzZShwbG90PT0ndHlwZSAxJywKICAgICAgICAgICBnMjEgPC0gcGxvdF9seShkYXRhQTEsIHggPSB+ZmVjaGEpICU+JQogICAgICAgICAgICAgYWRkX2xpbmVzKHkgPSB+ZGF0YUExJHJldG9ybm9zLCBuYW1lID0gIkFQUExFIiwgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDE5LDEzNSwxNzEpJywgd2lkdGggPSAyKSkgJT4lIAogICAgICAgICAgICAgYWRkX2xpbmVzKHkgPSB+ZGF0YU0xJHJldG9ybm9zLCBuYW1lID0gIk1JQ1JPU09GVCIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JnYigxNTMsMTcxLDI1NCknLCB3aWR0aCA9IDIpKSAlPiUKICAgICAgICAgICAgIGxheW91dCgKICAgICAgICAgICAgICAgdGl0bGUgPSAiUkVUT1JOT1MgKGFyaXRtw6l0aWNvcykgQVBQTEUgJiBNSUNST1NPRlQiLAogICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QoCiAgICAgICAgICAgICAgICAgcmFuZ2VzZWxlY3RvciA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICBidXR0b25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiMyBtbyIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiNiBtbyIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiMSB5ciIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICBzdGVwbW9kZSA9ICJiYWNrd2FyZCIpLAogICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJZVEQiLAogICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAieWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAidG9kYXRlIiksCiAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3RlcCA9ICJhbGwiKSkpLAogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHJhbmdlc2xpZGVyID0gbGlzdCh0eXBlID0gIkZlY2hhIikpLAogICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlJldG9ybm9zIikpLAogICAgICAgICAgIGlmZWxzZShwbG90PT0ndHlwZSAyJywKICAgICAgICAgICAgICAgICAgZzIyIDwtIHBsb3RfbHkoZGF0YUExLCB4ID0gfmZlY2hhKSAlPiUKICAgICAgICAgICAgICAgICAgICBhZGRfbGluZXMoeSA9IH5kYXRhQTEkcmV0Y3VtQSwgbmFtZSA9ICJBUFBMRSIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JnYigxOSwxMzUsMTcxKScsIHdpZHRoID0gMikpICU+JSAKICAgICAgICAgICAgICAgICAgICBhZGRfbGluZXMoeSA9IH5kYXRhTTEkcmV0Y3VtTSwgbmFtZSA9ICJNSUNST1NPRlQiLCBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoMTUzLDE3MSwyNTQpJywgd2lkdGggPSAyKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgbGF5b3V0KAogICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiUkVUT1JOT1MgQUNVTVVMQURPUyAoYXJpdG3DqXRpY29zKSBBUFBMRSAmIE1JQ1JPU09GVCIsCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlc2VsZWN0b3IgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICIzIG1vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCA9ICJtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXBtb2RlID0gImJhY2t3YXJkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIjYgbW8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwID0gIm1vbnRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcG1vZGUgPSAiYmFja3dhcmQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAiMSB5ciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAieWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXBtb2RlID0gImJhY2t3YXJkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIllURCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSAieWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXBtb2RlID0gInRvZGF0ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdGVwID0gImFsbCIpKSksCiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICByYW5nZXNsaWRlciA9IGxpc3QodHlwZSA9ICJGZWNoYSIpKSwKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlJldG9ybm9zIikpCiAgICAgICAgICAgICAgICAgICkjZmluIGlmZWxzZSBncmFmaWNvIHRpcG8gMgogICAgICAgICAgICkgI2ZpbiBwcmltZXIgaWZlbHNlIGdyYWZpY28gdGlwbyAxCiAgICAKICAgIGpfYXJpdD0gYnkocmV0b3Jub3NpbXBsZSxyZXRvcm5vc2ltcGxlJGFjY2lvbiwKICAgICAgICAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICAgICAgICAgbj1sZW5ndGgoeCRyZXRvcm5vcykKICAgICAgICAgICAgICAgICBtZWFuID0gc3VtKHgkcmV0b3Jub3MpL24KICAgICAgICAgICAgICAgICBza2V3bmVzcyA9ICgoc3VtKHgkcmV0b3Jub3MtbWVhbileMykvbikvKChzdW0oeCRyZXRvcm5vcy1tZWFuKV4yKS9uKV4oMy8yKQogICAgICAgICAgICAgICAgIGt1cnRvc2lzID0gKChzdW0oeCRyZXRvcm5vcy1tZWFuKV40KS9uKS8oKHN1bSh4JHJldG9ybm9zLW1lYW4pXjIpL24pXjIKICAgICAgICAgICAgICAgICBKQiA9IG4qKCgoc2tld25lc3NeMikvNikrKCgoa3VydG9zaXMtMyleMikvMjQpKQogICAgICAgICAgICAgICAgIGogPSBwYXN0ZSgncC12YWx1ZSA9JywxIC0gcGNoaXNxKEpCLGRmID0gMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgxIC0gcGNoaXNxKEpCLGRmID0gMik8MC4wNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcsIHNlIHJlY2hhemEgbGEgaGlwb3Rlc2lzIG51bGEgZGUgbm9ybWFsaWRhZCBwYXJhIGxvcyByZXRvcm5vcyBkZSBBcHBsZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLCBubyBzZSByZWNoYXphIGxhIGhpcG90ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgcGFyYSBsb3MgcmV0b3Jub3MgZGUgTWljcm9zb2Z0JykpfSkKICAgIH0jZmluIGVsc2UgaWYgcmV0b3Jub3M9bm8KICAKICAjZGViZW1vcyBnZW5lcmFsIGVsIHJlc3VsdGFkbyBub3JtYWw9PW5vIHkgZGFkbyBxdWUgZW4gYW1ib3MgY2Fzb3Mgc2UgcmVhbGl6YSBlbCB0ZXN0LCBwcm9ncmFtYW1vcyBsYSBzYWxpZGE6CiAgbm89IlNlIHJlYWxpesOzIHRlc3QgZGUgTm9ybWFsaWRhZCwgb2N1bHRhbmRvIHN1IHJlc3VsdGFkbyIKICAKICAjZGViZW1vcyBnZW5lcmFyIHRvZGFzIGxhcyBwb3NpYmxlcyBzYWxpZGFzCiAgaWZlbHNlKHJldHVybj09InllcyImIHBsb3Q9PSd0eXBlIDEnICYgbm9ybWFsPT0ieWVzIixyZXR1cm4obGlzdChnMTEsamxvZykpLAogICAgICAgICBpZmVsc2UocmV0dXJuPT0neWVzJyAmIHBsb3Q9PSd0eXBlIDInICYgbm9ybWFsPT0ieWVzIixyZXR1cm4obGlzdChnMTIsamxvZykpLAogICAgICAgICAgICAgICAgaWZlbHNlKHJldHVybj09J3llcycgJiBwbG90PT0ndHlwZSAxJyAmIG5vcm1hbD09Im5vIixyZXR1cm4obGlzdChnMTEsbm8pKSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmV0dXJuPT0neWVzJyAmIHBsb3Q9PSd0eXBlIDInICYgbm9ybWFsPT0ibm8iLHJldHVybihsaXN0KGcxMixubykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmV0dXJuPT0nbm8nICYgcGxvdD09J3R5cGUgMScgJiBub3JtYWw9PSJ5ZXMiLHJldHVybihsaXN0KGcyMSxqX2FyaXQpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZXR1cm49PSdubycgJiBwbG90PT0ndHlwZSAyJyAmIG5vcm1hbD09InllcyIscmV0dXJuKGxpc3QoZzIyLGpfYXJpdCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZXR1cm49PSdubycgJiBwbG90PT0ndHlwZSAxJyAmIG5vcm1hbD09Im5vIixyZXR1cm4obGlzdChnMjEsbm8pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJldHVybj09J25vJyAmIHBsb3Q9PSd0eXBlIDInICYgbm9ybWFsPT0ibm8iLHJldHVybihsaXN0KGcyMixubykpKSkpKSkpCiAgICAgICAgICAgICAgICAKICAgICAgICAgKSkKICAKICAKICB9I2ZpbiBmdW5jaW9uCmBgYAoKCgoKPGkgY2xhc3M9ImZhcyBmYS1jaGFydC1saW5lIj48L2k+IFJlc3VsdGFkb3MKLS0tLS0tLS0tLS0tLS0KYGBge3IgZmlnLmFzcD0wLjUsIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0xMH0KZmluYW5jZShkYXRhLCJ5ZXMiLCJ0eXBlIDEiLCJ5ZXMiKQpmaW5hbmNlKGRhdGEsIm5vIiwidHlwZSAxIiwieWVzIikKZmluYW5jZShkYXRhLCAieWVzIiwgInR5cGUgMiIsICJ5ZXMiKQpmaW5hbmNlKGRhdGEsICJubyIsICJ0eXBlIDIiLCAieWVzIikKYGBgCgoKCiMgPGEgaHJlZj0iIyI+PGkgY2xhc3M9ImZhcyBmYS1xdWVzdGlvbi1jaXJjbGUiPjwvaT4gPGI+UHJlZ3VudGEgMzwvYj48L2E+ey50YWJzZXQgLSAudGFic2V0LWZhZGV9CgoKLS0tLS0tLS0tLS0tLS0=